package cn.abyss.admin.response;

import cn.abyss.admin.enums.BaseAdminWebExceptionLevelEnum;
import org.springframework.stereotype.Component;

/**
 * Description:
 *
 * @author zhangsj
 * @date Created on 2020/12/2
 */
@Component
public class AbyResponse<T> {
    private static final String OK = "ok";
    private static final String ERROR = "error";
    private int code;
    private AbyResponse<T>.Meta meta;
    private T data;

    public AbyResponse() {
    }

    public AbyResponse success(int code, T data) {
        this.code = code;
        this.meta = new AbyResponse.Meta(true, "ok");
        this.data = data;
        return this;
    }

    public AbyResponse failure(int code, T data) {
        return this.failure(code, data, BaseAdminWebExceptionLevelEnum.INTERNAL_EXCEPTION.getCode());
    }

    public AbyResponse failure(int code, T data, int exceptionLevel) {
        this.code = code;
        this.meta = new AbyResponse.Meta(false, "error", exceptionLevel);
        this.data = data;
        return this;
    }

    public AbyResponse success() {
        this.meta = new AbyResponse.Meta(true, "ok");
        return this;
    }

    public AbyResponse success(T data) {
        this.meta = new AbyResponse.Meta(true, "ok");
        this.data = data;
        return this;
    }

    public AbyResponse failure() {
        this.meta = new AbyResponse.Meta(false, "error");
        return this;
    }

    public AbyResponse failure(String message) {
        return this.failure(message, BaseAdminWebExceptionLevelEnum.INTERNAL_EXCEPTION.getCode());
    }

    public AbyResponse failure(String message, int exceptionLevel) {
        this.meta = new AbyResponse.Meta(false, message, exceptionLevel);
        return this;
    }

    public AbyResponse failure(String message, T data) {
        return this.failure(message, data, BaseAdminWebExceptionLevelEnum.INTERNAL_EXCEPTION.getCode());
    }

    public AbyResponse failure(String message, T data, int exceptionLevel) {
        this.meta = new AbyResponse.Meta(false, message, exceptionLevel);
        this.data = data;
        return this;
    }

    public AbyResponse failure(String message, String exceptionCode, int exceptionLevel) {
        return this.failure(message, exceptionCode, (T) null, exceptionLevel);
    }

    public AbyResponse failure(String message, String exceptionCode, T data, int exceptionLevel) {
        this.meta = new AbyResponse.Meta(false, message, exceptionCode, exceptionLevel);
        this.data = data;
        return this;
    }

    public int getCode() {
        return this.code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public AbyResponse<T>.Meta getMeta() {
        return this.meta;
    }

    public void setMeta(AbyResponse<T>.Meta meta) {
        this.meta = meta;
    }

    public T getData() {
        return this.data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public class Meta {
        private boolean success;
        private String message;
        private String exceptionCode;
        private int exceptionLevel;

        public Meta(boolean success) {
            this.exceptionLevel = 1;
            if (success) {
                this.exceptionLevel = 0;
            }

            this.success = success;
        }

        public Meta(boolean success, String message) {
            this.exceptionLevel = 1;
            if (success) {
                this.exceptionLevel = 0;
            }

            this.success = success;
            this.message = message;
        }

        public Meta(boolean success, String message, int exceptionLevel) {
            this.exceptionLevel = exceptionLevel;
            this.success = success;
            this.message = message;
        }

        public Meta(boolean success, String message, String exceptionCode, int exceptionLevel) {
            this.success = success;
            this.message = message;
            this.exceptionCode = exceptionCode;
            this.exceptionLevel = exceptionLevel;
        }

        public boolean isSuccess() {
            return this.success;
        }

        public String getMessage() {
            return this.message;
        }

        public String getExceptionCode() {
            return this.exceptionCode;
        }

        public int getExceptionLevel() {
            return this.exceptionLevel;
        }
    }
}